# -*- coding: utf-8 -*-
# @Time    : 2024/11/10 14:03
# @Author  : CHNJX
# @File    : testcase.py
# @Desc    : 测试用例

from flask import Blueprint, request
from app.model import TestCase, TestCaseStep, db
from app.utils.response_handler import response_with_handler, success_response, error_response

test_case_bp = Blueprint('test_case', __name__)


# 获取所有测试用例
@test_case_bp.route('/', methods=['GET'])
@response_with_handler
def get_all_test_cases():
    cases = TestCase.query.all()
    return success_response([case.to_dict() for case in cases])


@test_case_bp.route('/module/<int:module_id>', methods=['GET'])
@response_with_handler
def get_test_cases_by_module(module_id):
    """获取指定模块的所有测试用例"""
    cases = TestCase.query.filter_by(module_id=module_id).all()
    return success_response([case.to_dict() for case in cases])


@test_case_bp.route('/<int:case_id>', methods=['GET'])
@response_with_handler
def get_test_case(case_id):
    """获取单个测试用例"""
    case = TestCase.query.get(case_id)
    if case is None:
        return error_response("测试用例不存在", code=404)
    return success_response(case.to_dict())


@test_case_bp.route('/', methods=['POST'])
@response_with_handler
def create_test_case():
    """创建测试用例"""
    data = request.get_json()
    required_fields = ['case_name', 'module_id']
    if not data or not all(field in data for field in required_fields):
        return error_response(f"缺少必要的参数: {', '.join(required_fields)}", code=400)

    try:
        case = TestCase(
            case_name=data['case_name'],
            module_id=data['module_id'],
            description=data.get('description')
        )
        db.session.add(case)
        db.session.flush()  # 获取case.id

        # 添加步骤
        if 'steps' in data:
            for index, step_data in enumerate(data['steps']):
                # 验证步骤数据
                if not step_data.get('step_id') and not step_data.get('custom_step_id'):
                    raise ValueError("步骤必须包含 step_id 或 custom_step_id")

                new_step = TestCaseStep(
                    test_case_id=case.id,
                    step_id=step_data.get('step_id'),  # 可以为空
                    custom_step_id=step_data.get('custom_step_id'),  # 可以为空
                    step_order=index,
                    parameters=step_data.get('parameters')
                )
                db.session.add(new_step)

        db.session.commit()
        return success_response(case.to_dict(), "测试用例创建成功")
    except ValueError as e:
        db.session.rollback()
        return error_response(str(e), code=400)
    except Exception as e:
        db.session.rollback()
        return error_response(f"创建失败: {str(e)}", code=500)


@test_case_bp.route('/<int:case_id>', methods=['PUT'])
@response_with_handler
def update_test_case(case_id):
    """更新测试用例"""
    case = TestCase.query.get(case_id)
    if case is None:
        return error_response("测试用例不存在", code=404)

    data = request.get_json()
    try:
        updated_case = case.update_test_case(data)
        return success_response(updated_case.to_dict(), "测试用例更新成功")
    except Exception as e:
        db.session.rollback()
        return error_response(f"更新失败: {str(e)}", code=500)


@test_case_bp.route('/<int:case_id>', methods=['DELETE'])
@response_with_handler
def delete_test_case(case_id):
    """删除测试用例"""
    case = TestCase.query.get(case_id)
    if case is None:
        return error_response("测试用例不存在", code=404)

    try:
        db.session.delete(case)
        db.session.commit()
        return success_response(message="测试用例删除成功")
    except Exception as e:
        db.session.rollback()
        return error_response(f"删除失败: {str(e)}", code=500)


@test_case_bp.route('/<int:case_id>/steps', methods=['GET'])
@response_with_handler
def get_case_steps(case_id):
    """获取测试用例的所有步骤"""
    case = TestCase.query.get(case_id)
    if case is None:
        return error_response("测试用例不存在", code=404)
    return success_response([step.to_dict() for step in case.steps])


@test_case_bp.route('/<int:case_id>/steps/reorder', methods=['PUT'])
@response_with_handler
def reorder_case_steps(case_id):
    """重新排序测试用例步骤"""
    case = TestCase.query.get(case_id)
    if case is None:
        return error_response("测试用例不存在", code=404)

    data = request.get_json()
    if not isinstance(data, dict):
        return error_response("请求数据格式错误", code=400)

    try:
        TestCaseStep.reorder_steps(case_id, data)
        return success_response(message="步骤顺序更新成功")
    except Exception as e:
        db.session.rollback()
        return error_response(f"更新顺序失败: {str(e)}", code=500)


@test_case_bp.route('/batch', methods=['POST'])
@response_with_handler
def batch_create_test_cases():
    """批量创建测试用例"""
    data = request.get_json()
    if not isinstance(data, list):
        return error_response("请求数据必须是数组格式", code=400)

    created_cases = []
    for item in data:
        required_fields = ['case_name', 'module_id']
        if not all(field in item for field in required_fields):
            return error_response(f"每个测试用例都必须包含以下字段: {', '.join(required_fields)}", code=400)

        try:
            case = TestCase.create_test_case(item)
            created_cases.append(case.to_dict())
        except Exception as e:
            db.session.rollback()
            return error_response(f"创建测试用例失败: {str(e)}", code=500)

    return success_response(created_cases, "批量创建测试用例成功")


@test_case_bp.route('/<int:case_id>/copy', methods=['POST'])
@response_with_handler
def copy_test_case(case_id):
    """复制测试用例"""
    source_case = TestCase.query.get(case_id)
    if source_case is None:
        return error_response("源测试用例不存在", code=404)

    data = request.get_json() or {}
    new_name = data.get('new_name', f"{source_case.case_name}_copy")

    try:
        # 创建新的测试用例数据
        new_case_data = {
            'case_name': new_name,
            'module_id': source_case.module_id,
            'description': source_case.description,
            'steps': [{
                'step_id': step.step_id,
                'parameters': step.parameters
            } for step in source_case.steps]
        }

        # 创建新的测试用例
        new_case = TestCase.create_test_case(new_case_data)
        return success_response(new_case.to_dict(), "测试用例复制成功")
    except Exception as e:
        db.session.rollback()
        return error_response(f"复制失败: {str(e)}", code=500)